package com.accesshollywood.components;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.HierarchyBoundsListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;

import org.jdesktop.swingx.VerticalLayout;

import com.accesshollywood.grfxOrdering.panels.OrderListPanel;
import com.accesshollywood.grfxOrdering.panels.OrderTree2;
import com.accesshollywood.grfxOrdering.panels.SingleOrderPanel;
import com.accesshollywood.trace.Trace;

public class FoldablePanel extends JPanel {
	public enum FOLD_SPEED {
		FAST,
		SLOW
	};

	public enum FOLD_STATE {
		OPEN,
		CLOSED
	};

	public Component	parent;
	public JButton		btnFoldUp;
	public JComponent	headerPanel;
	public JComponent	foldUpPanel;

	private boolean		folded		= false;

	public int			foldMax		= 100;
	int					foldY		= 0;
	int					foldStep	= 5;

	double				fastFPS		= 1.0;
	double				slowFPS		= 5.0;

	Timer				animFoldTimer;
	AnimateSwing		animFold;
	public FOLD_STATE	foldState	= FOLD_STATE.OPEN;

	public FoldablePanel() {
		super();

		this.setLayout(new VerticalLayout());
	}

	public void setHeaderAndFoldUp(JComponent headerPanel, JComponent foldUpPanel, final FOLD_STATE foldState) {
		this.headerPanel = headerPanel;
		this.foldUpPanel = foldUpPanel;
		// this.foldState = foldState;
		addFoldUpCheck();

		add(this.headerPanel);
		add(this.foldUpPanel);

		foldUpPanel.addHierarchyBoundsListener(new HierarchyBoundsListener() {

			@Override
			public void ancestorMoved(HierarchyEvent arg0) {
				System.out.println("moved");
			}

			@Override
			public void ancestorResized(HierarchyEvent arg0) {
				calcFoldMax();

				switch (foldState) {
					case OPEN:
						break;
					case CLOSED:
						doFoldUnfold(FOLD_SPEED.FAST);
						break;
				}
				FoldablePanel.this.foldUpPanel.removeHierarchyBoundsListener(this);
			}
		});
	}

	public void addFoldUpCheck() {
		btnFoldUp = new JButton();

		btnFoldUp.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				doFoldUnfold(FOLD_SPEED.SLOW);
			}
		});
		btnFoldUp.setIcon(UIManager.getIcon("Tree.collapsedIcon"));

		btnFoldUp.setText("");
		btnFoldUp.setOpaque(false);
		btnFoldUp.setContentAreaFilled(false);
		btnFoldUp.setBorderPainted(false);

		btnFoldUp.setMaximumSize(new Dimension(20, 20));
		btnFoldUp.setMinimumSize(new Dimension(20, 20));
		btnFoldUp.setPreferredSize(new Dimension(20, 20));
		btnFoldUp.setAlignmentX(LEFT_ALIGNMENT);

		headerPanel.add(btnFoldUp, 0);
	}

	public void doFoldUnfold(FOLD_SPEED speed) {
		int foldMin = 0;
		double fps = 1.0;
		switch (speed) {
			case FAST:
				fps = fastFPS;
				break;
			case SLOW:
				fps = slowFPS;
				break;
		}
		folded = !folded;

		calcFoldMax();

		if (!folded) {
			animFold = new AnimateSwing(foldMin, foldMax, (foldMax - foldMin) / fps, new animateFold());
			btnFoldUp.setIcon(UIManager.getIcon("Tree.expandedIcon"));
		} else {
			animFold = new AnimateSwing(foldMax, foldMin, (foldMin - foldMax) / fps, new animateFold());
			btnFoldUp.setIcon(UIManager.getIcon("Tree.collapsedIcon"));
		}
		animFoldTimer = new Timer(1, animFold);
		animFold.startTimer(animFoldTimer);
	}

	public void calcFoldMax() {
		foldMax = Math.max(foldUpPanel.getBounds().height, foldMax);
	}

	public class animateFold implements AnimSwing {
		@Override
		public void animateParameter(Number newValue) {
			Dimension preferredSize = foldUpPanel.getPreferredSize();
			foldUpPanel.setPreferredSize(new Dimension(preferredSize.width, newValue.intValue()));
			revalidate();
		}

		@Override
		public void animateFinished() {
			if (parent instanceof OrderTree2) {
				switch (foldState) { // this is what it WAS, switch it to what it IS, now that the animation is done
					case OPEN:
						foldState = FOLD_STATE.CLOSED;
						((OrderListPanel) ((OrderTree2) parent).parent).unfoldedOrderIDs.remove((Integer) ((SingleOrderPanel) FoldablePanel.this).model.getId());
						break;
					case CLOSED:
						foldState = FOLD_STATE.OPEN;
						((OrderListPanel) ((OrderTree2) parent).parent).unfoldedOrderIDs.add((Integer) ((SingleOrderPanel) FoldablePanel.this).model.getId());
						break;
				}
			}
		}
	}

}
